package com.ld.poetry.controller;

import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.ld.poetry.aop.LoginCheck;
import com.ld.poetry.config.PoetryResult;
import com.ld.poetry.constants.CommonConst;
import com.ld.poetry.dao.LabelMapper;
import com.ld.poetry.dao.SortMapper;
import com.ld.poetry.entity.Label;
import com.ld.poetry.entity.Sort;
import com.ld.poetry.utils.CommonQuery;
import com.ld.poetry.utils.cache.PoetryCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 分类标签 前端控制器
 * </p>
 *
 * @author sara
 * @since 2021-09-14
 */
@RestController
@RequestMapping("/webInfo")
public class SortLabelController {

    @Autowired
    private SortMapper sortMapper;

    @Autowired
    private LabelMapper labelMapper;

    @Autowired
    private CommonQuery commonQuery;

    /**
     * 获取分类标签信息
     */
    @GetMapping("/getSortInfo")
    public PoetryResult<List<Sort>> getSortInfo() {
        return PoetryResult.success(commonQuery.getSortInfo());
    }

    /**
     * 保存分类信息
     * 
     * 功能说明：
     * 1. 保存新的分类信息到数据库
     * 2. 需要管理员权限（@LoginCheck(0)）
     * 3. 保存后清除分类缓存
     * 
     * 请求参数：
     * @param sort 分类信息对象，包含以下字段：
     *   - sortName: 分类名称（必填）
     *   - sortDescription: 分类描述（必填）
     *   - priority: 分类优先级（必填）
     *   - sortType: 分类类型（可选，默认为普通分类）
     * 
     * 返回结果：
     * @return PoetryResult 操作结果
     *   - 成功：返回成功信息
     *   - 失败：返回错误信息（如：信息不全、优先级未配置）
     * 
     * 处理流程：
     * 1. 验证必填字段是否完整
     * 2. 验证优先级是否配置
     * 3. 保存分类信息到数据库
     * 4. 清除分类缓存
     * 
     * 注意事项：
     * 1. 需要管理员权限才能操作
     * 2. 分类名称和描述不能为空
     * 3. 必须配置分类优先级
     * 4. 保存后会清除分类缓存，确保数据一致性
     */
    @PostMapping("/saveSort")
    @LoginCheck(0)
    public PoetryResult saveSort(@RequestBody Sort sort) {
        // 验证必填字段：分类名称和描述不能为空
        if (!StringUtils.hasText(sort.getSortName()) || !StringUtils.hasText(sort.getSortDescription())) {
            return PoetryResult.fail("分类名称和分类描述不能为空！");
        }

        // 验证必填字段：分类优先级必须配置
        if (sort.getPriority() == null) {
            return PoetryResult.fail("分类必须配置优先级！");
        }

        // 保存分类信息到数据库
        sortMapper.insert(sort);
        
        // 清除分类缓存，确保下次查询获取最新数据
        PoetryCache.remove(CommonConst.SORT_INFO);
        
        return PoetryResult.success();
    }


    /**
     * 删除分类信息
     * 
     * 功能说明：
     * 1. 根据分类ID删除指定的分类
     * 2. 需要管理员权限（@LoginCheck(0)）
     * 3. 删除后清除分类缓存
     * 
     * 请求参数：
     * @param id 分类ID（必填）
     *   - 通过URL参数传递
     *   - 必须是有效的分类ID
     * 
     * 返回结果：
     * @return PoetryResult 操作结果
     *   - 成功：返回成功信息
     *   - 失败：返回错误信息（如：分类不存在）
     * 
     * 处理流程：
     * 1. 根据ID删除分类记录
     * 2. 清除分类缓存
     * 3. 返回操作结果
     * 
     * 注意事项：
     * 1. 需要管理员权限才能操作
     * 2. 删除操作不可恢复
     * 3. 删除分类前应确保没有关联的文章
     * 4. 删除后会清除分类缓存，确保数据一致性
     */
    @GetMapping("/deleteSort")
    @LoginCheck(0)
    public PoetryResult deleteSort(@RequestParam("id") Integer id) {
        // 根据ID删除分类记录
        sortMapper.deleteById(id);
        
        // 清除分类缓存，确保下次查询获取最新数据
        PoetryCache.remove(CommonConst.SORT_INFO);
        
        return PoetryResult.success();
    }


    /**
     * 更新分类信息
     * 
     * 功能说明：
     * 1. 根据分类ID更新分类信息
     * 2. 需要管理员权限（@LoginCheck(0)）
     * 3. 更新后清除分类缓存
     * 
     * 请求参数：
     * @param sort 分类信息对象，包含以下字段：
     *   - id: 分类ID（必填）
     *   - sortName: 分类名称（可选）
     *   - sortDescription: 分类描述（可选）
     *   - priority: 分类优先级（可选）
     *   - sortType: 分类类型（可选）
     * 
     * 返回结果：
     * @return PoetryResult 操作结果
     *   - 成功：返回成功信息
     *   - 失败：返回错误信息（如：分类不存在）
     * 
     * 处理流程：
     * 1. 根据ID更新分类记录
     * 2. 清除分类缓存
     * 3. 返回操作结果
     * 
     * 注意事项：
     * 1. 需要管理员权限才能操作
     * 2. 分类ID必须存在
     * 3. 只更新传入的字段，未传入的字段保持不变
     * 4. 更新后会清除分类缓存，确保数据一致性
     */
    @PostMapping("/updateSort")
    @LoginCheck(0)
    public PoetryResult updateSort(@RequestBody Sort sort) {
        // 根据ID更新分类记录
        sortMapper.updateById(sort);
        
        // 清除分类缓存，确保下次查询获取最新数据
        PoetryCache.remove(CommonConst.SORT_INFO);
        
        return PoetryResult.success();
    }


    /**
     * 查询所有分类列表
     * 
     * 功能说明：
     * 1. 获取所有分类信息列表
     * 2. 不分页，返回全部数据
     * 3. 无需权限验证，所有用户可访问
     * 
     * 请求参数：
     * 无参数
     * 
     * 返回结果：
     * @return PoetryResult<List<Sort>> 分类列表
     *   - code: 状态码
     *   - msg: 状态信息
     *   - data: 分类列表数据，包含以下字段：
     *     - id: 分类ID
     *     - sortName: 分类名称
     *     - sortDescription: 分类描述
     *     - sortType: 分类类型
     *     - priority: 分类优先级
     * 
     * 处理流程：
     * 1. 创建查询构造器
     * 2. 执行查询获取所有分类
     * 3. 返回分类列表
     * 
     * 注意事项：
     * 1. 返回结果未做分页处理
     * 2. 返回的是所有状态的分类
     * 3. 结果未做排序处理
     * 4. 适用于数据量较小的场景
     */
    @GetMapping("/listSort")
    public PoetryResult<List<Sort>> listSort() {
        // 使用LambdaQueryChainWrapper构建查询并执行
        // 返回所有分类列表
        return PoetryResult.success(new LambdaQueryChainWrapper<>(sortMapper).list());
    }


    /**
     * 保存标签信息
     * 
     * 功能说明：
     * 1. 保存新的标签信息到数据库
     * 2. 需要管理员权限（@LoginCheck(0)）
     * 3. 保存后清除分类缓存
     * 
     * 请求参数：
     * @param label 标签信息对象，包含以下字段：
     *   - labelName: 标签名称（必填）
     *   - labelDescription: 标签描述（必填）
     *   - sortId: 所属分类ID（必填）
     * 
     * 返回结果：
     * @return PoetryResult 操作结果
     *   - 成功：返回成功信息
     *   - 失败：返回错误信息（如：信息不全、分类ID不存在）
     * 
     * 处理流程：
     * 1. 验证必填字段是否完整
     * 2. 保存标签信息到数据库
     * 3. 清除分类缓存
     * 
     * 注意事项：
     * 1. 需要管理员权限才能操作
     * 2. 标签名称和描述不能为空
     * 3. 必须指定所属分类ID
     * 4. 保存后会清除分类缓存，确保数据一致性
     */
    @PostMapping("/saveLabel")
    @LoginCheck(0)
    public PoetryResult saveLabel(@RequestBody Label label) {
        // 验证必填字段：标签名称、描述和分类ID不能为空
        if (!StringUtils.hasText(label.getLabelName()) || 
            !StringUtils.hasText(label.getLabelDescription()) || 
            label.getSortId() == null) {
            return PoetryResult.fail("标签名称和标签描述和分类Id不能为空！");
        }

        // 保存标签信息到数据库
        labelMapper.insert(label);
        
        // 清除分类缓存，确保下次查询获取最新数据
        PoetryCache.remove(CommonConst.SORT_INFO);
        
        return PoetryResult.success();
    }


    /**
     * 删除标签信息
     * 
     * 功能说明：
     * 1. 根据标签ID删除指定的标签
     * 2. 需要管理员权限（@LoginCheck(0)）
     * 3. 删除后清除分类缓存
     * 
     * 请求参数：
     * @param id 标签ID（必填）
     *   - 通过URL参数传递
     *   - 必须是有效的标签ID
     * 
     * 返回结果：
     * @return PoetryResult 操作结果
     *   - 成功：返回成功信息
     *   - 失败：返回错误信息（如：标签不存在）
     * 
     * 处理流程：
     * 1. 根据ID删除标签记录
     * 2. 清除分类缓存
     * 3. 返回操作结果
     * 
     * 注意事项：
     * 1. 需要管理员权限才能操作
     * 2. 删除操作不可恢复
     * 3. 删除标签前应确保没有关联的文章
     * 4. 删除后会清除分类缓存，确保数据一致性
     */
    @GetMapping("/deleteLabel")
    @LoginCheck(0)
    public PoetryResult deleteLabel(@RequestParam("id") Integer id) {
        // 根据ID删除标签记录
        labelMapper.deleteById(id);
        
        // 清除分类缓存，确保下次查询获取最新数据
        PoetryCache.remove(CommonConst.SORT_INFO);
        
        return PoetryResult.success();
    }


    /**
     * 更新标签信息
     * 
     * 功能说明：
     * 1. 根据标签ID更新标签信息
     * 2. 需要管理员权限（@LoginCheck(0)）
     * 3. 更新后清除分类缓存
     * 
     * 请求参数：
     * @param label 标签信息对象，包含以下字段：
     *   - id: 标签ID（必填）
     *   - labelName: 标签名称（可选）
     *   - labelDescription: 标签描述（可选）
     *   - sortId: 所属分类ID（可选）
     * 
     * 返回结果：
     * @return PoetryResult 操作结果
     *   - 成功：返回成功信息
     *   - 失败：返回错误信息（如：标签不存在）
     * 
     * 处理流程：
     * 1. 根据ID更新标签记录
     * 2. 清除分类缓存
     * 3. 返回操作结果
     * 
     * 注意事项：
     * 1. 需要管理员权限才能操作
     * 2. 标签ID必须存在
     * 3. 只更新传入的字段，未传入的字段保持不变
     * 4. 更新后会清除分类缓存，确保数据一致性
     */
    @PostMapping("/updateLabel")
    @LoginCheck(0)
    public PoetryResult updateLabel(@RequestBody Label label) {
        // 根据ID更新标签记录
        labelMapper.updateById(label);
        
        // 清除分类缓存，确保下次查询获取最新数据
        PoetryCache.remove(CommonConst.SORT_INFO);
        
        return PoetryResult.success();
    }


    /**
     * 查询所有标签列表
     * 
     * 功能说明：
     * 1. 获取所有标签信息列表
     * 2. 不分页，返回全部数据
     * 3. 无需权限验证，所有用户可访问
     * 
     * 请求参数：
     * 无参数
     * 
     * 返回结果：
     * @return PoetryResult<List<Label>> 标签列表
     *   - code: 状态码
     *   - msg: 状态信息
     *   - data: 标签列表数据，包含以下字段：
     *     - id: 标签ID
     *     - labelName: 标签名称
     *     - labelDescription: 标签描述
     *     - sortId: 所属分类ID
     *     - countOfLabel: 标签使用次数
     * 
     * 处理流程：
     * 1. 创建查询构造器
     * 2. 执行查询获取所有标签
     * 3. 返回标签列表
     * 
     * 注意事项：
     * 1. 返回结果未做分页处理
     * 2. 返回的是所有状态的标签
     * 3. 结果未做排序处理
     * 4. 适用于数据量较小的场景
     */
    @GetMapping("/listLabel")
    public PoetryResult<List<Label>> listLabel() {
        // 使用LambdaQueryChainWrapper构建查询并执行
        // 返回所有标签列表
        return PoetryResult.success(new LambdaQueryChainWrapper<>(labelMapper).list());
    }


    /**
     * 获取分类和标签的完整列表
     * 
     * 功能说明：
     * 1. 一次性获取所有分类和标签信息
     * 2. 返回分类和标签的完整映射关系
     * 3. 无需权限验证，所有用户可访问
     * 
     * 请求参数：
     * 无参数
     * 
     * 返回结果：
     * @return PoetryResult<Map> 分类和标签的映射关系
     *   - code: 状态码
     *   - msg: 状态信息
     *   - data: 包含两个键值对的Map：
     *     - sorts: 分类列表，包含以下字段：
     *       - id: 分类ID
     *       - sortName: 分类名称
     *       - sortDescription: 分类描述
     *       - sortType: 分类类型
     *       - priority: 分类优先级
     *     - labels: 标签列表，包含以下字段：
     *       - id: 标签ID
     *       - labelName: 标签名称
     *       - labelDescription: 标签描述
     *       - sortId: 所属分类ID
     *       - countOfLabel: 标签使用次数
     * 
     * 处理流程：
     * 1. 创建结果Map对象
     * 2. 查询所有分类列表
     * 3. 查询所有标签列表
     * 4. 将分类和标签列表放入Map中
     * 5. 返回结果
     * 
     * 注意事项：
     * 1. 返回结果未做分页处理
     * 2. 返回的是所有状态的分类和标签
     * 3. 结果未做排序处理
     * 4. 适用于数据量较小的场景
     * 5. 前端可以根据sortId将标签关联到对应的分类
     */
    @GetMapping("/listSortAndLabel")
    public PoetryResult<Map> listSortAndLabel() {
        // 创建结果Map对象，用于存储分类和标签列表
        Map<String, List> map = new HashMap<>();
        
        // 查询所有分类列表并放入Map
        map.put("sorts", new LambdaQueryChainWrapper<>(sortMapper).list());
        
        // 查询所有标签列表并放入Map
        map.put("labels", new LambdaQueryChainWrapper<>(labelMapper).list());
        
        // 返回包含分类和标签列表的结果
        return PoetryResult.success(map);
    }
}
